﻿using Stardust.Common;
using Stardust.Common.Enum;
using Stardust.Common.Model;
using Stardust.Common.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Stardust.Client
{
    public class StardustClient
    {

        public static string ConfigCenterUrl { private set; get; }
        public static void SetConfigCenterUrl(string configCenterUrl)
        {
            ConfigCenterUrl = configCenterUrl;
        }
        
        public ServerNodeModel Node { get; private set; }

        public StardustClient(string serviceName, string version)
        {
            if (string.IsNullOrEmpty(ConfigCenterUrl))
            {
                throw new Exception("请先设置配置中心地址：ConfigCenterUrl");
            }
            //查询服务节点
            Node = NodeManager.GetNode(serviceName, version);
        }

        public TResult Invoke<TResult>(string controllerName, string actionName, object objParams = null, int timeout = 6000)
        {
            var jsonParams = string.Empty;
            if (objParams != null)
            {
                jsonParams = SerializerHelper.SerializeToString(objParams);
            }
            return Invoke<TResult>(controllerName, actionName, jsonParams, timeout);
        }
        
        public Task<TResult> InvokeAsync<TResult>(string controllerName, string actionName, object objParams = null, int timeout = 6000)
        {
            var jsonParams = string.Empty;
            if (objParams != null)
            {
                jsonParams = SerializerHelper.SerializeToString(objParams);
            }
            return InvokeAsync<TResult>(controllerName, actionName, jsonParams, timeout);
        }

        public TResult Invoke<TResult>(string controllerName, string actionName, string jsonParams = "", int timeout = 6000)
        {
            if (jsonParams == null)
            {
                jsonParams = string.Empty;
            }
            var url = Node.GetServiceUrl(controllerName, actionName);
            try
            {
                var json = HttpHelper.PostJsonToUrl(url, jsonParams, timeout);
                return SerializerHelper.DeserializeFromString<TResult>(json);
            }
            catch (WebException webExp)
            {
                var socketExp = webExp.InnerException as SocketException;
                if (socketExp != null && socketExp.SocketErrorCode == SocketError.ConnectionRefused)
                {
                    Node.Status = ServerNodeStatus.Disabled; //禁用
                }
                throw webExp;
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

        public Task<TResult> InvokeAsync<TResult>(string controllerName, string actionName, string jsonParams = "", int timeout = 6000)
        {
            if (jsonParams == null)
            {
                jsonParams = string.Empty;
            }
            var url = Node.GetServiceUrl(controllerName, actionName);
            try
            {
                return HttpHelper.PostJsonToUrlAsync(url, jsonParams, timeout).ContinueWith(task =>
                {
                    return SerializerHelper.DeserializeFromString<TResult>(task.Result);
                });
            }
            catch (WebException webExp)
            {
                var socketExp = webExp.InnerException as SocketException;
                if (socketExp != null && socketExp.SocketErrorCode == SocketError.ConnectionRefused)
                {
                    Node.Status = ServerNodeStatus.Disabled; //禁用
                }
                throw webExp;
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

    }

}
